package com.pai4j.zwiki.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * LLM服务
 * 集成大语言模型进行代码理解和内容生成
 *
 * @author pai4j
 * @since 2025-10-12
 */
@Slf4j
@Service
public class LLMService {

    private final ChatClient chatClient;

    @Value("${llm.openai.model:gpt-4}")
    private String model;

    public LLMService(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    /**
     * 生成项目架构总结（优化版 - 改进参数校验和异常处理）
     *
     * @param projectInfo 项目信息
     * @return 架构总结
     */
    public String generateArchitectureSummary(Map<String, Object> projectInfo) {
        log.info("开始生成项目架构总结");
        
        // 参数校验
        if (projectInfo == null || projectInfo.isEmpty()) {
            log.warn("项目信息为空，无法生成架构总结");
            return "项目信息不足，无法生成架构总结";
        }

        try {
            String prompt = buildArchitectureSummaryPrompt(projectInfo);
            
            String response = chatClient.prompt()
                    .user(prompt)
                    .call()
                    .content();

            // 检查响应有效性
            if (response == null || response.trim().isEmpty()) {
                log.warn("LLM返回空的架构总结");
                return "架构总结生成中，请稍后...";
            }
            
            log.info("架构总结生成完成，长度: {} 字符", response.length());
            return response;
            
        } catch (Exception e) {
            log.error("生成架构总结失败: {}", e.getMessage(), e);
            return "架构总结暂时无法生成，分析仍在继续...";
        }
    }

    /**
     * 生成代码摘要（优化版 - 改进参数校验和错误处理）
     *
     * @param prompt 提示词（可以是代码或其他分析请求）
     * @return 代码摘要或分析结果
     */
    public String generateCodeSummary(String prompt) {
        // 参数校验
        if (prompt == null || prompt.trim().isEmpty()) {
            log.warn("提示词为空，返回空结果");
            return "";
        }
        
        // 长度检查（防止超出 LLM 限制）
        if (prompt.length() > 200000) {
            log.warn("提示词过长 ({} 字符)，进行截断", prompt.length());
            prompt = prompt.substring(0, 200000) + "\n... [提示词过长，已截断]";
        }

        try {
            String response = chatClient.prompt()
                    .user(prompt)
                    .call()
                    .content();
            
            // 检查响应是否有效
            if (response == null || response.trim().isEmpty()) {
                log.warn("LLM返回空响应");
                return "分析结果生成中，请稍后...";
            }
            
            return response;
            
        } catch (Exception e) {
            log.error("生成代码摘要失败: {}", e.getMessage(), e);
            // 返回友好的错误提示，而不是空字符串
            return "暂时无法生成分析结果，请稍后重试。";
        }
    }

    /**
     * 生成论文章节内容（优化版 - 改进参数校验和异常处理）
     *
     * @param chapterName 章节名称
     * @param context     上下文信息
     * @return 章节内容
     */
    public String generateThesisChapter(String chapterName, Map<String, Object> context) {
        log.info("开始生成论文章节: {}", chapterName);
        
        // 参数校验
        if (chapterName == null || chapterName.trim().isEmpty()) {
            log.warn("章节名称为空");
            return "章节名称不能为空";
        }
        if (context == null) {
            log.warn("上下文信息为空，使用空上下文");
            context = new HashMap<>();
        }

        try {
            String prompt = buildThesisChapterPrompt(chapterName, context);
            
            String response = chatClient.prompt()
                    .user(prompt)
                    .call()
                    .content();

            // 检查响应有效性
            if (response == null || response.trim().isEmpty()) {
                log.warn("LLM返回空的章节内容: {}", chapterName);
                return "章节内容生成中，请稍后...";
            }
            
            log.info("论文章节生成完成: {}, 长度: {} 字符", chapterName, response.length());
            return response;
            
        } catch (Exception e) {
            log.error("生成论文章节失败: {}, 错误: {}", chapterName, e.getMessage(), e);
            return "第" + chapterName + "章节暂时无法生成，请稍后重试。";
        }
    }

    /**
     * 基于代码库回答问题（优化版 - 改进参数校验和上下文处理）
     *
     * @param question      用户问题
     * @param codeContext   相关代码上下文
     * @return 回答
     */
    public String answerQuestion(String question, List<String> codeContext) {
        log.info("开始回答问题: {}", question);
        
        // 参数校验
        if (question == null || question.trim().isEmpty()) {
            log.warn("用户问题为空");
            return "请输入您的问题";
        }
        if (codeContext == null) {
            log.warn("代码上下文为空，使用空列表");
            codeContext = new ArrayList<>();
        }

        try {
            StringBuilder promptBuilder = new StringBuilder();
            promptBuilder.append("你是一个代码分析助手。基于以下代码上下文回答用户的问题。\n\n");
            
            if (!codeContext.isEmpty()) {
                promptBuilder.append("代码上下文：\n");
                
                // 优化：提供更多上下文，但控制总长度
                int contextCount = Math.min(codeContext.size(), 10);
                int totalContextLength = 0;
                int maxTotalLength = 50000; // 最大上下文总长度
                
                for (int i = 0; i < contextCount; i++) {
                    String context = codeContext.get(i);
                    if (context != null && !context.trim().isEmpty()) {
                        if (totalContextLength + context.length() > maxTotalLength) {
                            break; // 超过最大长度，停止添加
                        }
                        promptBuilder.append("```\n").append(context).append("\n```\n\n");
                        totalContextLength += context.length();
                    }
                }
            } else {
                promptBuilder.append("（暂无代码上下文）\n\n");
            }
            
            promptBuilder.append("用户问题：").append(question).append("\n\n");
            promptBuilder.append("请给出详细、准确的回答。如果代码上下文不足以回答问题，请说明需要哪些额外信息。");

            String response = chatClient.prompt()
                    .user(promptBuilder.toString())
                    .call()
                    .content();
                    
            // 检查响应有效性
            if (response == null || response.trim().isEmpty()) {
                log.warn("LLM返回空回答");
                return "暂时无法回答您的问题，请稍后重试。";
            }
            
            log.info("问题回答完成，长度: {} 字符", response.length());
            return response;
            
        } catch (Exception e) {
            log.error("回答问题失败: {}", e.getMessage(), e);
            return "抱歉，回答您的问题时出现错误，请稍后重试。";
        }
    }

    /**
     * 构建架构总结提示词
     */
    private String buildArchitectureSummaryPrompt(Map<String, Object> projectInfo) {
        return String.format("""
                请分析以下项目信息，生成详细的架构总结报告（约1000字）：
                
                项目名称：%s
                文件总数：%s
                Java文件数：%s
                代码总行数：%s
                包数量：%s
                类数量：%s
                方法数量：%s
                
                请从以下几个方面进行分析：
                1. 项目整体架构特点
                2. 技术栈分析
                3. 模块划分与职责
                4. 设计模式应用
                5. 代码组织方式
                6. 潜在的优化建议
                
                请用专业、客观的语言撰写，适合作为毕业论文的技术分析部分。
                """,
                projectInfo.getOrDefault("projectName", "未知项目"),
                projectInfo.getOrDefault("totalFiles", 0),
                projectInfo.getOrDefault("totalJavaFiles", 0),
                projectInfo.getOrDefault("totalLines", 0),
                projectInfo.getOrDefault("packages", 0),
                projectInfo.getOrDefault("classes", 0),
                projectInfo.getOrDefault("methods", 0)
        );
    }

    /**
     * 构建论文章节提示词
     */
    private String buildThesisChapterPrompt(String chapterName, Map<String, Object> context) {
        String projectName = (String) context.getOrDefault("projectName", "本项目");
        
        return switch (chapterName) {
            case "background" -> String.format("""
                    请为项目"%s"撰写毕业论文的"项目背景与意义"章节（约800-1000字）。
                    
                    要求：
                    1. 阐述项目的研究背景和现实意义
                    2. 分析当前技术发展现状
                    3. 说明项目的创新点和价值
                    4. 语言要学术化、专业化
                    """, projectName);
            
            case "requirements" -> String.format("""
                    请为项目"%s"撰写毕业论文的"需求分析"章节（约1000-1200字）。
                    
                    项目统计信息：
                    - 总文件数：%s
                    - Java文件数：%s
                    - 代码行数：%s
                    
                    要求：
                    1. 描述系统的功能需求
                    2. 描述系统的非功能需求（性能、安全、可维护性等）
                    3. 绘制用例分析
                    4. 使用专业的需求分析方法
                    """, projectName,
                    context.getOrDefault("totalFiles", 0),
                    context.getOrDefault("totalJavaFiles", 0),
                    context.getOrDefault("totalLines", 0));
            
            case "systemDesign" -> String.format("""
                    请为项目"%s"撰写毕业论文的"系统设计"章节（约1200-1500字）。
                    
                    架构信息：
                    %s
                    
                    要求：
                    1. 描述系统的总体架构设计
                    2. 说明技术选型及理由
                    3. 阐述各模块的划分和职责
                    4. 描述关键技术实现方案
                    """, projectName, context.getOrDefault("architectureSummary", ""));
            
            default -> String.format("请为项目'%s'撰写'%s'章节内容（约1000字）。", projectName, chapterName);
        };
    }
}

